/* 2014/7/28 */
package cosmos.media;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents ID3V2 tag.
 * @author Leonardo
 *
 */
public class ID3v2 {

	/*
	/// <summary>
        /// Audio encryption
        /// </summary>
        private static readonly char[] AENC = "AENC".ToCharArray();

        /// <summary>
        /// Attached picture
        /// </summary>
        private static readonly char[] APIC = "APIC".ToCharArray();

        /// <summary>
        /// Comments
        /// </summary>
        private static readonly char[] COMM = "COMM".ToCharArray();

        /// <summary>
        /// Commercial frame
        /// </summary>
        private static readonly char[] COMR = "COMR".ToCharArray();

        /// <summary>
        /// Encryption method registration
        /// </summary>
        private static readonly char[] ENCR = "ENCR".ToCharArray();

        /// <summary>
        /// Equalization
        /// </summary>
        private static readonly char[] EQUA = "EQUA".ToCharArray();

        /// <summary>
        /// Event timing codes
        /// </summary>
        private static readonly char[] ETCO = "ETCO".ToCharArray();

        /// <summary>
        /// General encapsulated object
        /// </summary>
        private static readonly char[] GEOB = "GEOB".ToCharArray();

        /// <summary>
        /// Group identification registration
        /// </summary>
        private static readonly char[] GRID = "GRID".ToCharArray();

        /// <summary>
        /// Involved people list
        /// </summary>
        private static readonly char[] IPLS = "IPLS".ToCharArray();

        /// <summary>
        /// Linked information
        /// </summary>
        private static readonly char[] LINK = "LINK".ToCharArray();

        /// <summary>
        /// Music CD identifier
        /// </summary>
        private static readonly char[] MCDI = "MCDI".ToCharArray();

        /// <summary>
        /// MPEG location lookup table
        /// </summary>
        private static readonly char[] MLLT = "MLLT".ToCharArray();

        /// <summary>
        /// Ownership frame
        /// </summary>
        private static readonly char[] OWNE = "OWNE".ToCharArray();

        /// <summary>
        /// private static frame
        /// </summary>
        private static readonly char[] PRIV = "PRIV".ToCharArray();

        /// <summary>
        /// Play counter
        /// </summary>
        private static readonly char[] PCNT = "PCNT".ToCharArray();

        /// <summary>
        /// Popular meter
        /// </summary>
        private static readonly char[] POPM = "POPM".ToCharArray();

        /// <summary>
        /// Position synchronisation frame
        /// </summary>
        private static readonly char[] POSS = "POSS".ToCharArray();

        /// <summary>
        /// Recommended buffer size
        /// </summary>
        private static readonly char[] RBUF = "RBUF".ToCharArray();

        /// <summary>
        /// Relative volume adjustment
        /// </summary>
        private static readonly char[] RVAD = "RVAD".ToCharArray();

        /// <summary>
        /// Reverb
        /// </summary>
        private static readonly char[] RVRB = "RVRB".ToCharArray();

        /// <summary>
        /// Synchronized lyric/text
        /// </summary>
        private static readonly char[] SYLT = "SYLT".ToCharArray();

        /// <summary>
        /// Synchronized tempo codes
        /// </summary>
        private static readonly char[] SYTC = "SYTC".ToCharArray();

        /// <summary>
        /// Album/Movie/Show title
        /// </summary>
        private static readonly char[] TALB = "TALB".ToCharArray();

        /// <summary>
        /// BPM (beats per minute)
        /// </summary>
        private static readonly char[] TBPM = "TBPM".ToCharArray();

        /// <summary>
        /// Composer
        /// </summary>
        private static readonly char[] TCOM = "TCOM".ToCharArray();

        /// <summary>
        /// Content type
        /// </summary>
        private static readonly char[] TCON = "TCON".ToCharArray();

        /// <summary>
        /// Copyright message
        /// </summary>
        private static readonly char[] TCOP = "TCOP".ToCharArray();

        /// <summary>
        /// Date
        /// </summary>
        private static readonly char[] TDAT = "TDAT".ToCharArray();

        /// <summary>
        /// Playlist delay
        /// </summary>
        private static readonly char[] TDLY = "TDLY".ToCharArray();

        /// <summary>
        /// Encoded by
        /// </summary>
        private static readonly char[] TENC = "TENC".ToCharArray();

        /// <summary>
        /// Lyricist/Text writer
        /// </summary>
        private static readonly char[] TEXT = "TEXT".ToCharArray();

        /// <summary>
        /// File type
        /// </summary>
        private static readonly char[] TFLT = "TFLT".ToCharArray();

        /// <summary>
        /// Time
        /// </summary>
        private static readonly char[] TIME = "TIME".ToCharArray();

        /// <summary>
        /// Content group description
        /// </summary>
        private static readonly char[] TIT1 = "TIT1".ToCharArray();

        /// <summary>
        /// Title/song name/content description
        /// </summary>
        private static readonly char[] TIT2 = "TIT2".ToCharArray();

        /// <summary>
        /// Subtitle/Description refinement
        /// </summary>
        private static readonly char[] TIT3 = "TIT3".ToCharArray();

        /// <summary>
        /// Initial key
        /// </summary>
        private static readonly char[] TKEY = "TKEY".ToCharArray();

        /// <summary>
        /// Language(s)
        /// </summary>
        private static readonly char[] TLAN = "TLAN".ToCharArray();

        /// <summary>
        /// Length
        /// </summary>
        private static readonly char[] TLEN = "TLEN".ToCharArray();

        /// <summary>
        /// Media type
        /// </summary>
        private static readonly char[] TMED = "TMED".ToCharArray();

        /// <summary>
        /// Original album/movie/show title
        /// </summary>
        private static readonly char[] TOAL = "TOAL".ToCharArray();

        /// <summary>
        /// Original filename
        /// </summary>
        private static readonly char[] TOFN = "TOFN".ToCharArray();

        /// <summary>
        /// Original lyricist(s)/text writer(s)
        /// </summary>
        private static readonly char[] TOLY = "TOLY".ToCharArray();

        /// <summary>
        /// Original artist(s)/performer(s)
        /// </summary>
        private static readonly char[] TOPE = "TOPE".ToCharArray();

        /// <summary>
        /// Original release year
        /// </summary>
        private static readonly char[] TORY = "TORY".ToCharArray();

        /// <summary>
        /// File owner/licensee
        /// </summary>
        private static readonly char[] TOWN = "TOWN".ToCharArray();

        /// <summary>
        /// Lead performer(s)/Soloist(s)
        /// </summary>
        private static readonly char[] TPE1 = "TPE1".ToCharArray();

        /// <summary>
        /// Band/orchestra/accompaniment
        /// </summary>
        private static readonly char[] TPE2 = "TPE2".ToCharArray();

        /// <summary>
        /// Conductor/performer refinement
        /// </summary>
        private static readonly char[] TPE3 = "TPE3".ToCharArray();

        /// <summary>
        /// Interpreted, remixed, or otherwise modified by
        /// </summary>
        private static readonly char[] TPE4 = "TPE4".ToCharArray();

        /// <summary>
        /// Part of a set
        /// </summary>
        private static readonly char[] TPOS = "TPOS".ToCharArray();

        /// <summary>
        /// Publisher
        /// </summary>
        private static readonly char[] TPUB = "TPUB".ToCharArray();

        /// <summary>
        /// Track number/Position in set
        /// </summary>
        private static readonly char[] TRCK = "TRCK".ToCharArray();

        /// <summary>
        /// Recording dates
        /// </summary>
        private static readonly char[] TRDA = "TRDA".ToCharArray();

        /// <summary>
        /// Internet radio station name
        /// </summary>
        private static readonly char[] TRSN = "TRSN".ToCharArray();

        /// <summary>
        /// Internet radio station owner
        /// </summary>
        private static readonly char[] TRSO = "TRSO".ToCharArray();

        /// <summary>
        /// Size
        /// </summary>
        private static readonly char[] TSIZ = "TSIZ".ToCharArray();

        /// <summary>
        /// ISRC (international standard recording code)
        /// </summary>
        private static readonly char[] TSRC = "TSRC".ToCharArray();

        /// <summary>
        /// Software/Hardware and settings used for encoding
        /// </summary>
        private static readonly char[] TSSE = "TSSE".ToCharArray();

        /// <summary>
        /// Year
        /// </summary>
        private static readonly char[] TYER = "TYER".ToCharArray();

        /// <summary>
        /// User defined text information frame
        /// </summary>
        private static readonly char[] TXXX = "TXXX".ToCharArray();

        /// <summary>
        /// Unique file identifier
        /// </summary>
        private static readonly char[] UFID = "UFID".ToCharArray();

        /// <summary>
        /// Terms of use
        /// </summary>
        private static readonly char[] USER = "USER".ToCharArray();

        /// <summary>
        /// Unsychronized lyric/text transcription
        /// </summary>
        private static readonly char[] USLT = "USLT".ToCharArray();

        /// <summary>
        /// Commercial information
        /// </summary>
        private static readonly char[] WCOM = "WCOM".ToCharArray();

        /// <summary>
        /// Copyright/Legal information
        /// </summary>
        private static readonly char[] WCOP = "WCOP".ToCharArray();

        /// <summary>
        /// Official audio file web page
        /// </summary>
        private static readonly char[] WOAF = "WOAF".ToCharArray();

        /// <summary>
        /// Official artist/performer web page
        /// </summary>
        private static readonly char[] WOAR = "WOAR".ToCharArray();

        /// <summary>
        /// Official audio source web page
        /// </summary>
        private static readonly char[] WOAS = "WOAS".ToCharArray();

        /// <summary>
        /// Official Internet radio station home page
        /// </summary>
        private static readonly char[] WORS = "WORS".ToCharArray();

        /// <summary>
        /// Payment
        /// </summary>
        private static readonly char[] WPAY = "WPAY".ToCharArray();

        /// <summary>
        /// Publishers official web page
        /// </summary>
        private static readonly char[] WPUB = "WPUB".ToCharArray();

        /// <summary>
        /// User defined URL link frame
        /// </summary>
        private static readonly char[] WXXX = "WXXX".ToCharArray(); 
	 
	 */
	private ID3v2Frame[] frames;
	
	public void load(byte[] bytes) {
		List<ID3v2Frame> frameList = new ArrayList<>();
		
		int i;
		int j;
		int position = 0;
		int currentIndex = 0;
		while (position < bytes.length) {
			byte[] headerBytes = new byte[ID3v2FrameHeader.TOTAL_LENGTH];
			for (i = currentIndex, j = 0; i < currentIndex + ID3v2FrameHeader.TOTAL_LENGTH;
                    i++, j++) {
            	headerBytes[j] = bytes[i];
            	position++;
            }
			currentIndex = position;
                
            ID3v2FrameHeader header = new ID3v2FrameHeader();
            header.load(headerBytes);
                
            int frameSize = (int)header.getFrameSize();
            byte[] contentBytes = new byte[frameSize];
            for (i = currentIndex, j = 0; i < currentIndex + frameSize; i++, j++) {
            	contentBytes[j] = bytes[i];
            }
                
            ID3v2Frame frame = new ID3v2Frame();
            frame.setHeader(header);
            frame.setContent(contentBytes);
            frameList.add(frame);
		}
		
		frames = frameList.toArray(new ID3v2Frame[0]);
	}
	
	public byte[] save() {
		// Not implemented.
		return new byte[0];
	}
	
	private boolean compareFrameID(char[] constant, byte[] frameID) {
		if (constant == null && frameID == null) {
            return true;
        }
        else if (constant == null || frameID == null) {
            return false;
        }
        else if (constant.length != frameID.length) {
            return false;
        }
        else {
            for (int i = 0; i < constant.length; i++) {
                if (constant[i] != (char)frameID[i]) {
                    return false;
                }
            }
        }

        return true;
	}
	/*
	public byte[] getTitle() {
		for (ID3v2Frame frame : frames) {
            if (CompareFrameID(TIT2, frame.getHeader().getFrameID()))
            {
                return frame.getContent();
            }
        }

        return null;
	}	
	
	public byte[] Artist
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(TPE1, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }

    public byte[] Album
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(TALB, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }

    public byte[] Track
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(TRCK, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }

    public byte[] Year
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(TYER, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }

    public byte[] Type
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(TCON, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }

    public byte[] Comment
    {
        get
        {
            foreach (ID3V2Frame frame in _frames)
            {
                if (CompareFrameID(COMM, frame.Header.FrameID))
                {
                    return frame.Content;
                }
            }

            return null;
        }
    }*/
}
